home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / PASCAL / 0187.ZIP / SNAKE.PAS < prev    next >
Pascal/Delphi Source File  |  1985-01-20  |  7KB  |  316 lines

  1. program snake;
  2.  
  3. const
  4.    playerchar    = 'I';
  5.    snakechar     = 'S';
  6.    moneychar     = '$';
  7.    doorchar      = '#';
  8.  
  9.    upcommand     = 'U';
  10.    downcommand   = 'N';
  11.    leftcommand   = 'H';
  12.    rightcommand  = 'J';
  13.  
  14.    snakelength   =  5;
  15.    height        = 23;
  16.    width         = 39;
  17.    clearscreen   = 26;
  18.    moneyworth    = 25;
  19.  
  20. type
  21.    coordinate = record
  22.       x : integer;
  23.       y : integer;
  24.       end;
  25.    snaketype = array[1..snakelength] of coordinate;
  26.    thing = (playerthing, snakething, moneything, doorthing, emptything, scorething);
  27.  
  28. var
  29.    snake : snaketype;
  30.    player, money, door : coordinate;
  31.    score : integer;
  32.    left, eaten : boolean;
  33.  
  34.    screen : array[0..width] of array[0..height] of thing;
  35.  
  36.    lookslike : array[thing] of char;
  37.  
  38. (*
  39.  * returns a random integer between min and max
  40.  *)
  41.  
  42. function rand(min, max: integer) : integer;
  43.  
  44. begin
  45.    rand := min + random(max-min+1);
  46. end;
  47.  
  48. procedure instructions;
  49.  
  50. var
  51.    answer : char;
  52.  
  53. begin
  54.    write('Do you want instructions? ');
  55.    readln(answer);
  56.    while not (answer in ['y','n','Y','N']) do
  57.       begin
  58.       writeln('Please enter ''Yes'' or ''No''.');
  59.       readln(answer);
  60.       end;
  61.    if (answer = 'y') or (answer = 'Y') then
  62.       begin
  63.       writeln;
  64.       writeln('The object of SNAKE is to get as much money to the door as possible.');
  65.       writeln('The snake tries to prevent you. As you get more money, he tries');
  66.       writeln('more and more successfully. You move up, down, left and right');
  67.       writeln('by typing U, N, H and J respectively. You cannot move diagonally');
  68.       writeln('though the snake can.');
  69.       writeln;
  70.       write('Type return to continue ');
  71.       readln(answer);
  72.       end;
  73. end;
  74.  
  75. (*
  76.  * sets up all the variables
  77.  *)
  78.  
  79. procedure initialize;
  80.  
  81. var
  82.    x, y : integer;
  83.  
  84. begin
  85.    instructions;
  86.    for x := 0 to width do
  87.       for y := 0 to height do
  88.          screen[x][y] := emptything;
  89.    randomize;
  90.    lookslike[snakething] := snakechar;
  91.    lookslike[playerthing] := playerchar;
  92.    lookslike[moneything] := moneychar;
  93.    lookslike[emptything] := ' ';
  94.    lookslike[doorthing] := doorchar;
  95.    left := false;
  96.    eaten := false;
  97.    score := 0;
  98.    for x := 0 to 10 do
  99.       screen[x, 0] := scorething;
  100.    write(chr(clearscreen));
  101. end;
  102.  
  103. (*
  104.  * returns true if the position is valid and empty
  105.  *)
  106.  
  107. function freespot(pos : coordinate) : boolean;
  108.  
  109. begin
  110.    if (pos.x in [0..width]) and (pos.y in [0..height]) then
  111.       freespot := screen[pos.x, pos.y] = emptything
  112.    else freespot := false;
  113. end;
  114.  
  115. (*
  116.  * assigns the coordinates of a position on the screen that is not being used
  117.  *)
  118.  
  119. procedure makespace(var newpos : coordinate; forwhat : thing);
  120.  
  121. begin
  122.    with newpos do
  123.       begin
  124.          repeat
  125.             x := rand(0, width - 1);
  126.             y := rand(0, height - 1);
  127.          until freespot(newpos);
  128.          gotoxy(x, y);
  129.          write(lookslike[forwhat]);
  130.          screen[x, y] := forwhat;
  131.       end;
  132. end;
  133.  
  134. (*
  135.  * placenearby finds a free coordinate adjacent to the argument coordinate
  136.  * and places the thing there.
  137.  *)
  138.  
  139. procedure placenearby(var near, coord : coordinate);
  140.  
  141. var
  142.    deltax, deltay : integer;
  143.  
  144. begin
  145.    repeat
  146.       repeat
  147.          deltax := rand(-1, 1);
  148.          deltay := rand(-1, 1);
  149.       until (deltax <> 0) or (deltay <> 0);
  150.       near.x := coord.x + deltax;
  151.       near.y := coord.y + deltay;
  152.    until (freespot(near) or ((near.x = player.x) and (near.y = player.y)));
  153.    gotoxy(near.x,near.y);
  154.    screen[near.x, near.y] := snakething;
  155.    write(lookslike[snakething]);
  156. end;
  157.  
  158. (*
  159.  * removes whatever is at the coordinates from the terminal screen
  160.  * and the array screen.
  161.  *)
  162.  
  163. procedure remove(pos : coordinate);
  164.  
  165. begin
  166.    gotoxy(pos.x, pos.y);
  167.    write(' ');
  168.    screen[pos.x, pos.y] := emptything;
  169. end;
  170.  
  171. procedure takegold;
  172.  
  173. begin
  174.    score := score + moneyworth;
  175.    gotoxy(0,0);
  176.    write('$',score);
  177.    screen[money.x, money.y] := emptything;
  178.    makespace(money, moneything);
  179. end;
  180.  
  181. (*
  182.  * position all of the items in the game making sure that none of them
  183.  * overlap.
  184.  *)
  185.  
  186. procedure placeobjects;
  187.  
  188. var
  189.    snakebody : integer;
  190.  
  191. begin
  192.    makespace(snake[1], snakething);
  193.    for snakebody := 2 to snakelength do
  194.       placenearby(snake[snakebody], snake[snakebody - 1]);
  195.    makespace(player, playerthing);
  196.    makespace(money, moneything);
  197.    makespace(door, doorthing);
  198. end;
  199.  
  200. (*
  201.  * read the player's move from the keyboard, not input so that the letter
  202.  * will not be echoed and mess up the display.
  203.  *)
  204.  
  205. procedure playermove;
  206.  
  207. var
  208.    command : char;
  209.    oldpos  : coordinate;
  210.  
  211. begin
  212.    oldpos := player;
  213.    read(kbd, command);
  214.    with player do
  215.       begin
  216.       case command of
  217.          upcommand : if y > 0 then y := y - 1;
  218.          downcommand : if y < height then y := y + 1;
  219.          leftcommand : if x > 0 then x := x - 1;
  220.          rightcommand : if x < width then x := x + 1;
  221.       end;
  222.       if screen[x, y] = scorething then
  223.          player := oldpos
  224.       else
  225.          begin
  226.          remove(oldpos);
  227.          if (player.x = money.x) and (player.y = money.y) then
  228.             takegold
  229.          else if (player.x = door.x) and (player.y = door.y) then
  230.             left := true;
  231.          gotoxy(x, y);
  232.          write(playerchar);
  233.          screen[x, y] := playerthing;
  234.          end;
  235.       end;
  236. end;
  237.  
  238. (*
  239.  * used by snakemove to figure out which way is the direction
  240.  * toward the player
  241.  *)
  242.  
  243. function sign(x : integer) : integer;
  244.  
  245. begin
  246.    if x = 0 then
  247.       sign := 0
  248.    else if x > 0 then
  249.       sign := 1
  250.    else
  251.       sign := -1;
  252. end;
  253.  
  254. (*
  255.  * snake moves randomly at first, then it goes more directly toward
  256.  * the player
  257.  *)
  258.  
  259. procedure snakemove;
  260.  
  261. var
  262.    newpos : coordinate;
  263.    bodypart : integer;
  264.  
  265. begin
  266.    if rand(0, score) <= 100 then
  267.       placenearby(newpos, snake[1])
  268.    else
  269.       begin
  270.       newpos.x := snake[1].x + sign(player.x - snake[1].x);
  271.       newpos.y := snake[1].y + sign(player.y - snake[1].y);
  272.       if (screen[newpos.x, newpos.y] = emptything) or
  273.          ((newpos.x = player.x) and (newpos.y = player.y)) then
  274.          begin
  275.          gotoxy(newpos.x, newpos.y);
  276.          write(snakechar);
  277.          screen[newpos.x, newpos.y] := snakething;
  278.          end
  279.       else
  280.          placenearby(newpos, snake[1]);
  281.       end;
  282.    remove(snake[snakelength]);
  283.    if (newpos.x = player.x) and (newpos.y = player.y) then
  284.       eaten := true;
  285.    for bodypart := snakelength downto 2 do
  286.       begin
  287.       snake[bodypart] := snake[bodypart - 1];
  288.       if (snake[bodypart].x = player.x) and (snake[bodypart].y = player.y) then
  289.          eaten := true;
  290.       end;
  291.    snake[1] := newpos;
  292. end;
  293.  
  294.  
  295. begin
  296.    initialize;
  297.    placeobjects;
  298.    repeat
  299.       playermove;
  300.       if not left then
  301.          snakemove;
  302.    until left or eaten;
  303.    gotoxy(0, height);
  304.    writeln;
  305.    if left then
  306.       writeln('You hace escaped with $',score)
  307.    else
  308.       writeln('The snake has eaten you.');
  309. end.
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.